import * as BABYLON from '@babylonjs/core';
import * as GUI from '@babylonjs/gui';
import { JsonHelper } from "./JsonHelper";
import { BabylonDevice2d } from "./modules/2d/BabylonDevice2d";
import { BabylonScene2d } from "./modules/2d/BabylonScene2d";
import { BabylonScene } from "./modules/BabylonScene";
import { KrRecordable } from "./modules/KrData";
import { BabylonCanvas } from './modules/BabylonCanvas';
import { Device2D } from './modules/2d/controls/Device2D';
import { TWcsScene, TWcsSceneDevice3d, TWcsSceneDevice2d } from './models';
import { StandardDevice2d } from './modules/2d/devices';

export class ClassHelper {
  private static registers: Map<string, any> = new Map<string, any>([
    ['BabylonDevice2d', (scene: BabylonScene, data: TWcsSceneDevice2d)=>new BabylonDevice2d(scene, data)],
    ['StandardDevice2d', (data: TWcsSceneDevice2d)=>new StandardDevice2d(data)],
    ['BabylonScene2d', (canvas: BabylonCanvas, tWcsScene: TWcsScene) => new BabylonScene2d(canvas, tWcsScene)],
    ['DirectionalLight', (name: string, direction: BABYLON.Vector3, scene: BABYLON.Scene)=> new BABYLON.DirectionalLight(name, direction, scene)],
    ['HemisphericLight', (name: string, direction: BABYLON.Vector3, scene: BABYLON.Scene)=> new BABYLON.HemisphericLight(name, direction, scene)],
    ['ArcRotateCamera', (name: string, alpha: number, beta: number, radius: number, target: BABYLON.Vector3, scene: BABYLON.Scene) => new BABYLON.ArcRotateCamera(name, alpha, beta, radius, target, scene)]
  ]);

  public static createInstance<T>(cls: string, ...args: any[]): T | null {
    const ctor = ClassHelper.registers.get(cls);
    if(ctor) {
      return ctor(...args);
    }
    return null;
  }

  public static setPropertiesFromJson<T extends KrRecordable>(
    target: T,
    jsonStr: string | KrRecordable,
    ignoreCase: boolean = true
  ): void {
    let jsonObj: KrRecordable;

    // 判断输入类型，如果是字符串则解析为 JSON 对象
    if (typeof jsonStr === "string") {
      try {
        jsonObj = JsonHelper.toJson(jsonStr);
      } catch (error) {
        console.error("转化json字符串失败:", error);
        return;
      }
    } else {
      jsonObj = jsonStr;
    }
    // 获取目标对象的所有属性名
    const properties =Object.entries(Object.getOwnPropertyDescriptors(Object.getPrototypeOf(target)))
      .filter(([k, descriptor]) => descriptor.get || descriptor.set)
      .map(([k, descriptor]) => k);
    var fields = Object.keys(target);
    fields.push(...properties);
    // 遍历 JSON 对象的键值对并设置到目标对象实例的属性
    Object.keys(jsonObj).forEach((key) => {
      // 查找匹配的属性名
      const matchingKey = ignoreCase
        ? fields.find((targetKey) => targetKey.toLowerCase() === key.toLowerCase())
        : key;
      // 如果找到匹配的属性名，则设置其值
      if (matchingKey && matchingKey in target) {
        (target as any)[matchingKey] = (jsonObj as any)[key];
      }
    });
  }
}
